home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 7
/
Apprentice-Release7.iso
/
Environments
/
PowerLisp 2.01
/
Supplemental Documentation
/
Documentation
/
Chapter 06. Predicates
< prev
next >
Wrap
Text File
|
1995-03-27
|
37KB
|
884 lines
Common Lisp the Language, 2nd Edition
-------------------------------------------------------------------------------
6. Predicates
A predicate is a function that tests for some condition involving its arguments
and returns nil if the condition is false, or some non-nil value if the
condition is true. One may think of a predicate as producing a Boolean value,
where nil stands for false and anything else stands for true. Conditional
control structures such as cond, if, when, and unless test such Boolean values.
We say that a predicate is true when it returns a non-nil value, and is false
when it returns nil; that is, it is true or false according to whether the
condition being tested is true or false.
By convention, the names of predicates usually end in the letter p (which
stands for ``predicate''). Common Lisp uses a uniform convention in hyphenating
names of predicates. If the name of the predicate is formed by adding a p to an
existing name, such as the name of a data type, a hyphen is placed before the
final p if and only if there is a hyphen in the existing name. For example,
number begets numberp but standard-char begets standard-char-p. On the other
hand, if the name of a predicate is formed by adding a prefixing qualifier to
the front of an existing predicate name, the two names are joined with a hyphen
and the presence or absence of a hyphen before the final p is not changed. For
example, the predicate string-lessp has no hyphen before the p because it is
the string version of lessp (a MacLisp function that has been renamed < in
Common Lisp). The name string-less-p would incorrectly imply that it is a
predicate that tests for a kind of object called a string-less, and the name
stringlessp would connote a predicate that tests whether something has no
strings (is ``stringless'')!
The control structures that test Boolean values only test for whether or not
the value is nil, which is considered to be false. Any other value is
considered to be true. Often a predicate will return nil if it ``fails'' and
some useful value if it ``succeeds''; such a function can be used not only as a
test but also for the useful value provided in case of success. An example is
member.
If no better non-nil value is available for the purpose of indicating success,
by convention the symbol t is used as the ``standard'' true value.
-------------------------------------------------------------------------------
* Logical Values
* Data Type Predicates
o General Type Predicates
o Specific Data Type Predicates
* Equality Predicates
* Logical Operators
-------------------------------------------------------------------------------
6.1. Logical Values
The names nil and t are constants in Common Lisp. Although they are symbols
like any other symbols, and appear to be treated as variables when evaluated,
it is not permitted to modify their values. See defconstant.
[Constant]
nil
The value of nil is always nil. This object represents the logical false value
and also the empty list. It can also be written ().
[Constant]
t
The value of t is always t.
-------------------------------------------------------------------------------
6.2. Data Type Predicates
Perhaps the most important predicates in Lisp are those that deal with data
types; that is, given a data object one can determine whether or not it belongs
to a given type, or one can compare two type specifiers.
-------------------------------------------------------------------------------
* General Type Predicates
* Specific Data Type Predicates
-------------------------------------------------------------------------------
6.2.1. General Type Predicates
If a data type is viewed as the set of all objects belonging to the type, then
the typep function is a set membership test, while subtypep is a subset test.
[Function]
typep object type
typep is a predicate that is true if object is of type type, and is false
otherwise. Note that an object can be ``of'' more than one type, since one type
can include another. The type may be any of the type specifiers mentioned in
chapter 4 except that it may not be or contain a type specifier list whose
first element is function or values. A specifier of the form (satisfies fn) is
handled simply by applying the function fn to object (see funcall); the object
is considered to be of the specified type if the result is not nil.
[change_begin]
X3J13 voted in January 1989 (ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS) to change
typep to give specialized array and complex type specifiers the same meaning
for purposes of type discrimination as they have for declaration purposes. Of
course, this also applies to such type specifiers as vector and simple-array
(see section 4.5). Thus
(typep foo '(array bignum))
in the first edition asked the question, Is foo an array specialized to hold
bignums? but under the new interpretation asks the question, Could the array
foo have resulted from giving bignum as the :element-type argument to
make-array?
[change_end]
[Function]
subtypep type1 type2
The arguments must be type specifiers that are acceptable to typep. The two
type specifiers are compared; this predicate is true if type1 is definitely a
(not necessarily proper) subtype of type2. If the result is nil, however, then
type1 may or may not be a subtype of type2 (sometimes it is impossible to tell,
especially when satisfies type specifiers are involved). A second returned
value indicates the certainty of the result; if it is true, then the first
value is an accurate indication of the subtype relationship. Thus there are
three possible result combinations:
t t type1 is definitely a subtype of type2
nil t type1 is definitely not a subtype of type2
nil nil subtypep could not determine the relationship
[change_begin]
X3J13 voted in January 1989 (SUBTYPEP-TOO-VAGUE) to place certain
requirements upon the implementation of subtypep, for it noted that
implementations in many cases simply ``give up'' and return the two values nil
and nil when in fact it would have been possible to determine the relationship
between the given types. The requirements are as follows, where it is
understood that a type specifier s involves a type specifier u if either s
contains an occurrence of u directly or s contains a type specifier w defined
by deftype whose expansion involves u.
* subtypep is not permitted to return a second value of nil unless one or
both of its arguments involves satisfies, and, or, not, or member.
* subtypep should signal an error when one or both of its arguments
involves values or the list form of the function type specifier.
* subtypep must always return the two values t and t in the case where its
arguments, after expansion of specifiers defined by deftype, are equal.
In addition, X3J13 voted to clarify that in some cases the relationships
between types as reflected by subtypep may be implementation-specific. For
example, in an implementation supporting only one type of floating-point
number, (subtypep 'float 'long-float) would return t and t, since the two types
would be identical.
Note that satisfies is an exception because relationships between types
involving satisfies are undecidable in general, but (as X3J13 noted) and, or,
not, and member are merely very messy to deal with. In all likelihood these
will not be addressed unless and until someone is willing to write a careful
specification that covers all the cases for the processing of these type
specifiers by subtypep. The requirements stated above were easy to state and
probably suffice for most cases of interest.
X3J13 voted in January 1989 (ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS) to change
subtypep to give specialized array and complex type specifiers the same meaning
for purposes of type discrimination as they have for declaration purposes. Of
course, this also applies to such type specifiers as vector and simple-array
(see section 4.5).
If A and B are type specifiers (other than *, which technically is not a type
specifier anyway), then (array A) and (array B) represent the same type in a
given implementation if and only if they denote arrays of the same specialized
representation in that implementation; otherwise they are disjoint. To put it
another way, they represent the same type if and only if
(upgraded-array-element-type 'A) and (upgraded-array-element-type 'B) are the
same type. Therefore
(subtypep '(array A) '(array B))
is true if and only if (upgraded-array-element-type 'A) is the same type as
(upgraded-array-element-type 'B).
The complex type specifier is treated in a similar but subtly different manner.
If A and B are two type specifiers (but not *, which technically is not a type
specifier anyway), then (complex A) and (complex B) represent the same type in
a given implementation if and only if they refer to complex numbers of the same
specialized representation in that implementation; otherwise they are disjoint.
Note, however, that there is no function called make-complex that allows one to
specify a particular element type (then to be upgraded); instead, one must
describe specialized complex numbers in terms of the actual types of the parts
from which they were constructed. There is no number of type (or rather,
representation) float as such; there are only numbers of type single-float,
numbers of type double-float, and so on. Therefore we want (complex
single-float) to be a subtype of (complex float).
The rule, then, is that (complex A) and (complex B) represent the same type
(and otherwise are disjoint) in a given implementation if and only if either
the type A is a subtype of B, or (upgraded-complex-part-type 'A) and
(upgraded-complex-part-type 'B) are the same type. In the latter case (complex
A) and (complex B) in fact refer to the same specialized representation.
Therefore
(subtypep '(complex A) '(complex B))
is true if and only if the results of (upgraded-complex-part-type 'A) and
(upgraded-complex-part-type 'B) are the same type.
Under this interpretation
(subtypep '(complex single-float) '(complex float))
must be true in all implementations; but
(subtypep '(array single-float) '(array float))
is true only in implementations that do not have a specialized array
representation for single-float elements distinct from that for float elements
in general.
[change_end]
-------------------------------------------------------------------------------
6.2.2. Specific Data Type Predicates
The following predicates test for individual data types.
[Function]
null object
null is true if its argument is (), and otherwise is false. This is the same
operation performed by the function not; however, not is normally used to
invert a Boolean value, whereas null is normally used to test for an empty
list. The programmer can therefore express intent by the choice of function
name.
(null x) == (typep x 'null) == (eq x '())
[Function]
symbolp object
symbolp is true if its argument is a symbol, and otherwise is false.
(symbolp x) == (typep x 'symbol)
-------------------------------------------------------------------------------
Compatibility note: The Interlisp equivalent of symbolp is called litatom.
-------------------------------------------------------------------------------
[Function]
atom object
The predicate atom is true if its argument is not a cons, and otherwise is
false. Note that (atom '()) is true, because () nil.
(atom x) == (typep x 'atom) == (not (typep x 'cons))
-------------------------------------------------------------------------------
Compatibility note: In some Lisp dialects, notably Interlisp, only symbols and
numbers are considered to be atoms; arrays and strings are considered to be
neither atoms nor lists (conses).
-------------------------------------------------------------------------------
[Function]
consp object
The predicate consp is true if its argument is a cons, and otherwise is false.
Note that the empty list is not a cons, so (consp '()) == (consp 'nil) => nil.
(consp x) == (typep x 'cons) == (not (typep x 'atom))
-------------------------------------------------------------------------------
Compatibility note: Some Lisp implementations call this function pairp or
listp. The name pairp was rejected for Common Lisp because it emphasizes too
strongly the dotted-pair notion rather than the usual usage of conses in lists.
On the other hand, listp too strongly implies that the cons is in fact part of
a list, which after all it might not be; moreover, () is a list, though not a
cons. The name consp seems to be the appropriate compromise.
-------------------------------------------------------------------------------
[Function]
listp object
listp is true if its argument is a cons or the empty list (), and otherwise is
false. It does not check for whether the list is a ``true list'' (one
terminated by nil) or a ``dotted list'' (one terminated by a non-null atom).
(listp x) == (typep x 'list) == (typep x '(or cons null))
[Function]
numberp object
numberp is true if its argument is any kind of number, and otherwise is false.
(numberp x) == (typep x 'number)
[Function]
integerp object
integerp is true if its argument is an integer, and otherwise is false.
(integerp x) == (typep x 'integer)
-------------------------------------------------------------------------------
Compatibility note: In MacLisp this is called fixp. Users have been confused as
to whether this meant integerp or fixnump, and so the name integerp has been
adopted here.
-------------------------------------------------------------------------------
[Function]
rationalp object
rationalp is true if its argument is a rational number (a ratio or an integer),
and otherwise is false.
(rationalp x) == (typep x 'rational)
[Function]
floatp object
floatp is true if its argument is a floating-point number, and otherwise is
false.
(floatp x) == (typep x 'float)
[change_begin]
[Function]
realp object
X3J13 voted in March 1989 (REAL-NUMBER-TYPE) to add the function realp. realp
is true if its argument is a real number, and otherwise is false.
(realp x) == (typep x 'real)
[change_end]
[Function]
complexp object
complexp is true if its argument is a complex number, and otherwise is false.
(complexp x) == (typep x 'complex)
[Function]
characterp object
characterp is true if its argument is a character, and otherwise is false.
(characterp x) == (typep x 'character)
[Function]
stringp object
stringp is true if its argument is a string, and otherwise is false.
(stringp x) == (typep x 'string)
[Function]
bit-vector-p object
bit-vector-p is true if its argument is a bit-vector, and otherwise is false.
(bit-vector-p x) == (typep x 'bit-vector)
[Function]
vectorp object
vectorp is true if its argument is a vector, and otherwise is false.
(vectorp x) == (typep x 'vector)
[Function]
simple-vector-p object
vectorp is true if its argument is a simple general vector, and otherwise is
false.
(simple-vector-p x) == (typep x 'simple-vector)
[Function]
simple-string-p object
simple-string-p is true if its argument is a simple string, and otherwise is
false.
(simple-string-p x) == (typep x 'simple-string)
[Function]
simple-bit-vector-p object
simple-bit-vector-p is true if its argument is a simple bit-vector, and
otherwise is false.
(simple-bit-vector-p x) == (typep x 'simple-bit-vector)
[Function]
arrayp object
arrayp is true if its argument is an array, and otherwise is false.
(arrayp x) == (typep x 'array)
[Function]
packagep object
packagep is true if its argument is a package, and otherwise is false.
(packagep x) == (typep x 'package)
[Function]
functionp object
[old_change_begin]
functionp is true if its argument is suitable for applying to arguments, using
for example the funcall or apply function. Otherwise functionp is false.
functionp is always true of symbols, lists whose car is the symbol lambda, any
value returned by the function special form, and any values returned by the
function compile when the first argument is nil.
[old_change_end]
[change_begin]
X3J13 voted in June 1988 (FUNCTION-TYPE) to define
(functionp x) == (typep x 'function)
Because the vote also specifies that types cons and symbol are disjoint from
the type function, this is an incompatible change; now functionp is in fact
always false of symbols and lists.
[change_end]
[Function]
compiled-function-p object
compiled-function-p is true if its argument is any compiled code object, and
otherwise is false.
(compiled-function-p x) == (typep x 'compiled-function)
[old_change_begin]
[Function]
commonp object
commonp is true if its argument is any standard Common Lisp data type, and
otherwise is false.
(commonp x) == (typep x 'common)
[old_change_end]
[change_begin]
X3J13 voted in March 1989 (COMMON-TYPE) to remove the predicate commonp (and
the type common) from the language.
[change_end]
See also standard-char-p, string-char-p, streamp, random-state-p, readtablep,
hash-table-p, and pathnamep.
-------------------------------------------------------------------------------
6.3. Equality Predicates
Common Lisp provides a spectrum of predicates for testing for equality of two
objects: eq (the most specific), eql, equal, and equalp (the most general). eq
and equal have the meanings traditional in Lisp. eql was added because it is
frequently needed, and equalp was added primarily in order to have a version of
equal that would ignore type differences when comparing numbers and case
differences when comparing characters. If two objects satisfy any one of these
equality predicates, then they also satisfy all those that are more general.
[Function]
eq x y
(eq x y) is true if and only if x and y are the same identical object.
(Implementationally, x and y are usually eq if and only if they address the
same identical memory location.)
It should be noted that things that print the same are not necessarily eq to
each other. Symbols with the same print name usually are eq to each other
because of the use of the intern function. However, numbers with the same value
need not be eq, and two similar lists are usually not eq. For example:
(eq 'a 'b) is false.
(eq 'a 'a) is true.
(eq 3 3) might be true or false, depending on the implementation.
(eq 3 3.0) is false.
(eq 3.0 3.0) might be true or false, depending on the implementation.
(eq #c(3 -4) #c(3 -4))
might be true or false, depending on the implementation.
(eq #c(3 -4.0) #c(3 -4)) is false.
(eq (cons 'a 'b) (cons 'a 'c)) is false.
(eq (cons 'a 'b) (cons 'a 'b)) is false.
(eq '(a . b) '(a . b)) might be true or false.
(progn (setq x (cons 'a 'b)) (eq x x)) is true.
(progn (setq x '(a . b)) (eq x x)) is true.
(eq #\A #\A) might be true or false, depending on the implementation.
(eq "Foo" "Foo") might be true or false.
(eq "Foo" (copy-seq "Foo")) is false.
(eq "FOO" "foo") is false.
In Common Lisp, unlike some other Lisp dialects, the implementation is
permitted to make ``copies'' of characters and numbers at any time. (This
permission is granted because it allows tremendous performance improvements in
many common situations.) The net effect is that Common Lisp makes no guarantee
that eq will be true even when both its arguments are ``the same thing'' if
that thing is a character or number. For example:
(let ((x 5)) (eq x x)) might be true or false.
The predicate eql is the same as eq, except that if the arguments are
characters or numbers of the same type then their values are compared. Thus eql
tells whether two objects are conceptually the same, whereas eq tells whether
two objects are implementationally identical. It is for this reason that eql,
not eq, is the default comparison predicate for the sequence functions defined
in chapter 14.
-------------------------------------------------------------------------------
Implementation note: eq simply compares the two given pointers, so any kind of
object that is represented in an ``immediate'' fashion will indeed have
like-valued instances satisfy eq. In some implementations, for example, fixnums
and characters happen to ``work.'' However, no program should depend on this,
as other implementations of Common Lisp might not use an immediate
representation for these data types.
-------------------------------------------------------------------------------
[old_change_begin]
An additional problem with eq is that the implementation is permitted to
``collapse'' constants (or portions thereof) appearing in code to be compiled
if they are equal. An object is considered to be a constant in code to be
compiled if it is a self-evaluating form or is contained in a quote form. This
is why (eq "Foo" "Foo") might be true or false; in interpreted code it would
normally be false, because reading in the form (eq "Foo" "Foo") would construct
distinct strings for the two arguments to eq, but the compiler might choose to
use the same identical string or two distinct copies as the two arguments in
the call to eq. Similarly, (eq '(a . b) '(a . b)) might be true or false,
depending on whether the constant conses appearing in the quote forms were
collapsed by the compiler. However, (eq (cons 'a 'b) (cons 'a 'b)) is always
false, because every distinct call to the cons function necessarily produces a
new and distinct cons.
[old_change_end]
[change_begin]
X3J13 voted in March 1989 (QUOTE-SEMANTICS) to clarify that eval and compile
are not permitted either to copy or to coalesce (``collapse'') constants (see
eq) appearing in the code they process; the resulting program behavior must
refer to objects that are eql to the corresponding objects in the source code.
Only the compile-file/load process is permitted to copy or coalesce constants
(see section 25.1).
[change_end]
[Function]
eql x y
The eql predicate is true if its arguments are eq, or if they are numbers of
the same type with the same value, or if they are character objects that
represent the same character. For example:
(eql 'a 'b) is false.
(eql 'a 'a) is true.
(eql 3 3) is true.
(eql 3 3.0) is false.
(eql 3.0 3.0) is true.
(eql #c(3 -4) #c(3 -4)) is true.
(eql #c(3 -4.0) #c(3 -4)) is false.
(eql (cons 'a 'b) (cons 'a 'c)) is false.
(eql (cons 'a 'b) (cons 'a 'b)) is false.
(eql '(a . b) '(a . b)) might be true or false.
(progn (setq x (cons 'a 'b)) (eql x x)) is true.
(progn (setq x '(a . b)) (eql x x)) is true.
(eql #\A #\A) is true.
(eql "Foo" "Foo") might be true or false.
(eql "Foo" (copy-seq "Foo")) is false.
(eql "FOO" "foo") is false.
Normally (eql 1.0s0 1.0d0) would be false, under the assumption that 1.0s0 and
1.0d0 are of distinct data types. However, implementations that do not provide
four distinct floating-point formats are permitted to ``collapse'' the four
formats into some smaller number of them; in such an implementation (eql 1.0s0
1.0d0) might be true. The predicate = will compare the values of two numbers
even if the numbers are of different types.
If an implementation supports positive and negative zeros as distinct values
(as in the IEEE proposed standard floating-point format), then (eql 0.0 -0.0)
will be false. Otherwise, when the syntax -0.0 is read it will be interpreted
as the value 0.0, and so (eql 0.0 -0.0) will be true. The predicate = differs
from eql in that (= 0.0 -0.0) will always be true, because = compares the
mathematical values of its operands, whereas eql compares the representational
values, so to speak.
Two complex numbers are considered to be eql if their real parts are eql and
their imaginary parts are eql. For example, (eql #C(4 5) #C(4 5)) is true and
(eql #C(4 5) #C(4.0 5.0)) is false. Note that while (eql #C(5.0 0.0) 5.0) is
false, (eql #C(5 0) 5) is true. In the case of (eql #C(5.0 0.0) 5.0) the two
arguments are of different types and so cannot satisfy eql; that's all there is
to it. In the case of (eql #C(5 0) 5), however, #C(5 0) is not a complex number
but is always automatically reduced by the rule of complex canonicalization to
the integer 5, just as the apparent ratio 20/4 is always simplified to 5.
The case of (eql "Foo" "Foo") is discussed above in the description of eq.
While eql compares the values of numbers and characters, it does not compare
the contents of strings. To compare the characters of two strings, one should
use equal, equalp, string=, or string-equal.
-------------------------------------------------------------------------------
Compatibility note: The Common Lisp function eql is similar to the Interlisp
function eqp. However, eql considers 3 and 3.0 to be different, whereas eqp
considers them to be the same; eqp behaves like the Common Lisp = function, not
like eql, when both arguments are numbers.
-------------------------------------------------------------------------------
[Function]
equal x y
The equal predicate is true if its arguments are structurally similar
(isomorphic) objects. A rough rule of thumb is that two objects are equal if
and only if their printed representations are the same.
Numbers and characters are compared as for eql. Symbols are compared as for eq.
This method of comparing symbols can violate the rule of thumb for equal and
printed representations, but only in the infrequently occurring case of two
distinct symbols with the same print name.
Certain objects that have components are equal if they are of the same type and
corresponding components are equal. This test is implemented in a recursive
manner and may fail to terminate for circular structures.
For conses, equal is defined recursively as the two car's being equal and the
two cdr's being equal.
Two arrays are equal only if they are eq, with one exception: strings and
bit-vectors are compared element-by-element. If either argument has a fill
pointer, the fill pointer limits the number of elements examined by equal.
Uppercase and lowercase letters in strings are considered by equal to be
distinct. (In contrast, equalp ignores case distinctions in strings.)
-------------------------------------------------------------------------------
Compatibility note: In Lisp Machine Lisp, equal ignores the difference between
uppercase and lowercase letters in strings. This violates the rule of thumb
about printed representations, however, which is very useful, especially to
novices. It is also inconsistent with the treatment of single characters, which
in Lisp Machine Lisp are represented as fixnums.
-------------------------------------------------------------------------------
Two pathname objects are equal if and only if all the corresponding components
(host, device, and so on) are equivalent. (Whether or not uppercase and
lowercase letters are considered equivalent in strings appearing in components
depends on the file name conventions of the file system.) Pathnames that are
equal should be functionally equivalent.
[change_begin]
X3J13 voted in June 1989 (EQUAL-STRUCTURE) to clarify that equal never
recursively descends any structure or data type other than the ones explicitly
described above: conses, bit-vectors, strings, and pathnames. Numbers and
characters are compared as if by eql, and all other data objects are compared
as if by eq.
[change_end]
(equal 'a 'b) is false.
(equal 'a 'a) is true.
(equal 3 3) is true.
(equal 3 3.0) is false.
(equal 3.0 3.0) is true.
(equal #c(3 -4) #c(3 -4)) is true.
(equal #c(3 -4.0) #c(3 -4)) is false.
(equal (cons 'a 'b) (cons 'a 'c)) is false.
(equal (cons 'a 'b) (cons 'a 'b)) is true.
(equal '(a . b) '(a . b)) is true.
(progn (setq x (cons 'a 'b)) (equal x x)) is true.
(progn (setq x '(a . b)) (equal x x)) is true.
(equal #\A #\A) is true.
(equal "Foo" "Foo") is true.
(equal "Foo" (copy-seq "Foo")) is true.
(equal "FOO" "foo") is false.
To compare a tree of conses using eql (or any other desired predicate) on the
leaves, use tree-equal.
[Function]
equalp x y
Two objects are equalp if they are equal; if they are characters and satisfy
char-equal, which ignores alphabetic case and certain other attributes of
characters; if they are numbers and have the same numerical value, even if they
are of different types; or if they have components that are all equalp.
Objects that have components are equalp if they are of the same type and
corresponding components are equalp. This test is implemented in a recursive
manner and may fail to terminate for circular structures. For conses, equalp is
defined recursively as the two car's being equalp and the two cdr's being
equalp.
Two arrays are equalp if and only if they have the same number of dimensions,
the dimensions match, and the corresponding components are equalp. The
specializations need not match; for example, a string and a general array that
happens to contain the same characters will be equalp (though definitely not
equal). If either argument has a fill pointer, the fill pointer limits the
number of elements examined by equalp. Because equalp performs
element-by-element comparisons of strings and ignores the alphabetic case of
characters, case distinctions are therefore also ignored when equalp compares
strings.
Two symbols can be equalp only if they are eq, that is, the same identical
object.
[change_begin]
X3J13 voted in June 1989 (EQUAL-STRUCTURE) to specify that equalp compares
components of hash tables (see below), and to clarify that otherwise equalp
never recursively descends any structure or data type other than the ones
explicitly described above: conses, arrays (including bit-vectors and strings),
and pathnames. Numbers are compared for numerical equality (see =), characters
are compared as if by char-equal, and all other data objects are compared as if
by eq.
Two hash tables are considered the same by equalp if and only if they satisfy a
four-part test:
* They must be of the same kind; that is, equivalent :test arguments were
given to make-hash-table when the two hash tables were created.
* They must have the same number of entries (see hash-table-count).
* For every entry (key1, value1) in one hash table there must be a
corresponding entry (key2, value2) in the other, such that key1 and key2
are considered to be the same by the :test function associated with the
hash tables.
* For every entry (key1, value1) in one hash table and its corresponding
entry (key2, value2) in the other, such that key1 and key2 are the same,
equalp must be true of value1 and value2.
The four parts of this test are carried out in the order shown, and if some
part of the test fails, equalp returns nil and the other parts of the test are
not attempted.
If equalp must compare two structures and the defstruct definition for one used
the :type option and the other did not, then equalp returns nil.
If equalp must compare two structures and neither defstruct definition used the
:type option, then equalp returns t if and only if the structures have the same
type (that is, the same defstruct name) and the values of all corresponding
slots (slots having the same name) are equalp.
As part of the X3J13 discussion of this issue the following observations were
made. Object equality is not a concept for which there is a uniquely determined
correct algorithm. The appropriateness of an equality predicate can be judged
only in the context of the needs of some particular program. Although these
functions take any type of argument and their names sound very generic, equal
and equalp are not appropriate for every application. Any decision to use or
not use them should be determined by what they are documented to do rather than
by any abstract characterization of their function. If neither equal nor equalp
is found to be appropriate in a particular situation, programmers are
encouraged to create another operator that is appropriate rather than blame
equal or equalp for ``doing the wrong thing.''
Note that one consequence of the vote to change the rules of floating-point
contagion (CONTAGION-ON-NUMERICAL-COMPARISONS) (described in section 12.1) is
to make equalp a true equivalence relation on numbers.
[change_end]
(equalp 'a 'b) is false.
(equalp 'a 'a) is true.
(equalp 3 3) is true.
(equalp 3 3.0) is true.
(equalp 3.0 3.0) is true.
(equalp #c(3 -4) #c(3 -4)) is true.
(equalp #c(3 -4.0) #c(3 -4)) is true.
(equalp (cons 'a 'b) (cons 'a 'c)) is false.
(equalp (cons 'a 'b) (cons 'a 'b)) is true.
(equalp '(a . b) '(a . b)) is true.
(progn (setq x (cons 'a 'b)) (equalp x x)) is true.
(progn (setq x '(a . b)) (equalp x x)) is true.
(equalp #\A #\A) is true.
(equalp "Foo" "Foo") is true.
(equalp "Foo" (copy-seq "Foo")) is true.
(equalp "FOO" "foo") is true.
-------------------------------------------------------------------------------
6.4. Logical Operators
Common Lisp provides three operators on Boolean values: and, or, and not. Of
these, and and or are also control structures because their arguments are
evaluated conditionally. The function not necessarily examines its single
argument, and so is a simple function.
[Function]
not x
not returns t if x is nil, and otherwise returns nil. It therefore inverts its
argument considered as a Boolean value.
null is the same as not; both functions are included for the sake of clarity.
As a matter of style, it is customary to use null to check whether something is
the empty list and to use not to invert the sense of a logical value.
[Macro]
and {form}*
(and form1 form2 ... ) evaluates each form, one at a time, from left to right.
If any form evaluates to nil, the value nil is immediately returned without
evaluating the remaining forms. If every form but the last evaluates to a
non-nil value, and returns whatever the last form returns. Therefore in general
and can be used both for logical operations, where nil stands for false and
non-nil values stand for true, and as a conditional expression. An example
follows.
(if (and (>= n 0)
(< n (length a-simple-vector))
(eq (elt a-simple-vector n) 'foo))
(princ "Foo!"))
The above expression prints Foo! if element n of a-simple-vector is the symbol
foo, provided also that n is indeed a valid index for a-simple-vector. Because
and guarantees left-to-right testing of its parts, elt is not called if n is
out of range.
To put it another way, the and special form does short-circuit Boolean
evaluation, like the and then operator in Ada and what in some Pascal-like
languages is called cand (for ``conditional and''); the Lisp and special form
is unlike the Pascal or Ada and operator, which always evaluates both
arguments.
In the previous example writing
(and (>= n 0)
(< n (length a-simple-vector))
(eq (elt a-simple-vector n) 'foo)
(princ "Foo!"))
would accomplish the same thing. The difference is purely stylistic. Some
programmers never use expressions containing side effects within and,
preferring to use if or when for that purpose.
From the general definition, one can deduce that (and x) == x. Also, (and)
evaluates to t, which is an identity for this operation.
One can define and in terms of cond in this way:
(and x y z ... w) == (cond ((not x) nil)
((not y) nil)
((not z) nil)
...
(t w))
See if and when, which are sometimes stylistically more appropriate than and
for conditional purposes. If it is necessary to test whether a predicate is
true of all elements of a list or vector (element 0 and element 1 and element 2
and ...), then the function every may be useful.
[Macro]
or {form}*
(or form1 form2 ... ) evaluates each form, one at a time, from left to right.
If any form other than the last evaluates to something other than nil, or
immediately returns that non-nil value without evaluating the remaining forms.
If every form but the last evaluates to nil, or returns whatever evaluation of
the last of the forms returns. Therefore in general or can be used both for
logical operations, where nil stands for false and non-nil values stand for
true, and as a conditional expression.
To put it another way, the or special form does short-circuit Boolean
evaluation, like the or else operator in Ada and what in some Pascal-like
languages is called cor (for ``conditional or''); the Lisp or special form is
unlike the Pascal or Ada or operator, which always evaluates both arguments.
From the general definition, one can deduce that (or x) == x. Also, (or)
evaluates to nil, which is the identity for this operation.
One can define or in terms of cond in this way:
(or x y z ... w) == (cond (x) (y) (z) ... (t w))
See if and unless, which are sometimes stylistically more appropriate than or
for conditional purposes. If it is necessary to test whether a predicate is
true of one or more elements of a list or vector (element 0 or element 1 or
element 2 or ...), then the function some may be useful.
-------------------------------------------------------------------------------